﻿#region Copyright
//       Copyright (c) 2009 - Antoine Jaussoin - http://www.jaussoin.com/blog/
// 
//        This program is free software: you can redistribute it and/or modify
//        it under the terms of the GNU General Public License as published by
//        the Free Software Foundation, either version 3 of the License, or
//        (at your option) any later version.
// 
//        This program is distributed in the hope that it will be useful,
//        but WITHOUT ANY WARRANTY; without even the implied warranty of
//        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//        GNU General Public License for more details.
// 
//        You should have received a copy of the GNU General Public License
//        along with this program.  If not, see <http://www.gnu.org/licenses/>.
#endregion
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace FT.Architecture.Utils.Serialisation
{
    /// <summary>
    /// Helps with serialising objects from and to string
    /// </summary>
    public class Serialiser
    {
        /// <summary>
        /// Serialise an object into a Base 64 string. The object needs to be marked as Serializable.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string Serialise(object obj)
        {
            byte[] bytes = SerialiseBytes(obj);
            return Base64.FromBytes(bytes);
        }

        /// <summary>
        /// Serialise an object into an array of bytes. The object needs to be marked as Serializable.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static byte[] SerialiseBytes(object obj)
        {
            var memoryStream = new MemoryStream();
            var binaryFormatter = new BinaryFormatter();
            binaryFormatter.Serialize(memoryStream, obj);

            memoryStream.Flush();
            byte[] bytes = memoryStream.ToArray();

            return bytes;
        }

        /// <summary>
        /// Deserialise an object from a Base 64 string
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="serialisedObject"></param>
        /// <returns></returns>
        public static T Deserialise<T>(string serialisedObject)
        {
            return (T) Deserialise(serialisedObject);
        }

        /// <summary>
        /// Deserialise an object from a Base 64 string
        /// </summary>
        /// <param name="serialisedObject"></param>
        /// <returns></returns>
        public static object Deserialise(string serialisedObject)
        {
            byte[] bytes = Base64.ToBytes(serialisedObject);
            return DeserialiseBytes(bytes);
        }

        /// <summary>
        /// Deserialise an object from an array of bytes
        /// </summary>
        /// <param name="serialisedObject"></param>
        /// <returns></returns>
        public static object DeserialiseBytes(byte[] serialisedObject)
        {
            var memoryStream = new MemoryStream(serialisedObject);
            var binaryFormatter = new BinaryFormatter();

            return binaryFormatter.Deserialize(memoryStream);
        }
    }
}
